#region License
//-----------------------------------------------------------------------------
// Copyright (c) 2008, Aaron MacDougall, Daniel Jeffery
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of Aaron MacDougall or Daniel Jeffery nor the names of its contributors may
//   be used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
#endregion

namespace Agro2D
{
    /// <summary>
    /// Defines the type of collision test to be performed on a Sprite.
    /// </summary>
    public enum CollisionType
    {
        None,
        BoundingBox,
        PerPixel,
        Vector
    }

    /// <summary>
    /// All of a Sprite object's collision attributes collected together in a
    /// class. This is the same way that SpriteProperties works.
    /// </summary>
    public class CollisionProperties : ICloneable
    {       
        #region Fields
        /// <summary>
        /// The type of collision test to be performed on a Sprite.
        /// </summary>
        private CollisionType collisionType;
        /// <summary>
        /// The type of collision test to be performed on a Sprite.
        /// </summary>
        private Rectangle boundingBox;
        /// <summary>
        /// The collision groups that the Sprite belongs to.
        /// </summary>
        private CollisionGroups collisionGroups;
        /// <summary>
        /// The collision groups that the Sprite collides with.
        /// </summary>
        private CollisionGroups collidesWith;
        /// <summary>
        /// Vectors for Vector collision
        /// </summary>
        private Vector2[] vectors;
        /// <summary>
        /// Stored sloped for vectors
        /// </summary>
        private float slope;
        /// <summary>
        /// Stored sloped for vectors
        /// </summary>
        #endregion

        #region Properties
        /// <summary>
        /// The type of collision test to be performed on a Sprite.
        /// </summary>
        [ImportAttribute]
        public CollisionType CollisionType
        {
            get { return this.collisionType; }
            set { this.collisionType = value; }
        }
        /// <summary>
        /// The type of collision test to be performed on a Sprite.
        /// </summary>
        [ImportAttribute] 
        public Rectangle BoundingBox
        {
            get { return this.boundingBox; }
            set { this.boundingBox = value; }
        }
        /// <summary>
        /// The collision groups that the Sprite belongs to.
        /// </summary>
        [ImportAttribute] 
        public CollisionGroups CollisionGroups
        {
            get { return this.collisionGroups; }
            set { this.collisionGroups = value; }
        }
        /// <summary>
        /// The collision groups that the Sprite collides with.
        /// </summary>
        [ImportAttribute] 
        public CollisionGroups CollidesWith
        {
            get { return this.collidesWith; }
            set { this.collidesWith = value; }
        }
        /// <summary>
        /// Vectors for Vector collision
        /// </summary>
        [ImportAttribute] 
        public Vector2 LeftVector
        {
            get { return this.vectors[0]; }
            set { this.vectors[0] = value; }
        }

        /// <summary>
        /// Vectors for Vector collision
        /// </summary>
        [ImportAttribute]
        public Vector2 RightVector
        {
            get { return this.vectors[1]; }
            set { this.vectors[1] = value; }
        }
        /// <summary>
        /// Stored slope for vector collision
        /// </summary>
        public float Slope
        {
            get { return this.slope; }
            set { this.slope = value; }
        }
        
        #endregion

        #region Constructors/Destructors
        /// <summary>
        /// Default Constructor.
        /// </summary>
        public CollisionProperties()
        {
            this.CollisionType = CollisionType.None;
            this.BoundingBox = Rectangle.Empty;
            this.CollisionGroups = CollisionGroups.None;
            this.CollidesWith = CollisionGroups.None;
            this.vectors = new Vector2[2];
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="collisionType">
        /// The type of collision test to be performed on a Sprite.
        /// </param>
        /// <param name="boundingBox">
        /// The type of collision test to be performed on a Sprite.
        /// </param>
        /// <param name="collisionGroups">
        /// The collision groups that the Sprite collides with.
        /// </param>
        /// <param name="collidesWith">
        /// The collision groups that the Sprite collides with.
        /// </param>
        public CollisionProperties(
            CollisionType collisionType,
            Rectangle boundingBox,
            CollisionGroups collisionGroups,
            CollisionGroups collidesWith
            )
        {
            this.CollisionType = collisionType;
            this.BoundingBox = boundingBox;
            this.CollisionGroups = collisionGroups;
            this.CollidesWith = collidesWith;
            this.vectors = new Vector2[2];
        }
        #endregion


        #region IClonable Implementation
        /// <summary>
        /// Returns a cloned version of this object.
        /// </summary>
        /// <returns>Cloned version of this object.</returns>
        public object Clone()
        {
           CollisionProperties props =  new CollisionProperties(
                this.CollisionType,
                this.BoundingBox,
                this.CollisionGroups,
                this.CollidesWith
                );

           props.LeftVector = this.LeftVector;
           props.RightVector = this.RightVector;

           return props;
        }
        #endregion
    }
}